package net.sansi.v3correctserver.interceptor;

import cn.hutool.crypto.SecureUtil;
import lombok.extern.slf4j.Slf4j;
import net.sansi.v3correctserver.exception.ServiceException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Created by Fang
 * create time : 2024/2/2
 * IDE : IntelliJ IDEA
 * <p>
 * 权限验证拦截器
 * 用于检查是否为客户端的合法访问
 */

@Slf4j
@Component
public class AuthInterceptor implements HandlerInterceptor {

    @Value("${correct.sign-key:00000}")
    private String signKey;

    // 最近一次请求的签名
    // 格式 [固定10长度的16单调递增自然数，从1000000000开始][64长度的SHA256签名]
    // 如：10000000005ddb6e427a492322d16349aa5198dfdfa67124bed69c68a5fe2c50db2d8e6faf
    private static long lastIdx = 0L;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String sign = request.getHeader("sign");
        if (sign == null) throw new ServiceException("非法请求（签名丢失）");
        if (sign.length() != 64) throw new ServiceException("非法请求（签名长度错误）");
        String rand = sign.substring(0, 10), hash = sign.substring(10);
        synchronized (AuthInterceptor.class) {
            long idx = Long.parseLong(rand);
            if (idx <= lastIdx) throw new ServiceException("非法请求（签名过期）");
            lastIdx = idx;
        }
        String comp = SecureUtil.sha256(rand + signKey);
        if (comp.equals(hash)) return true;
        throw new ServiceException("签名验证失败！");
    }
}
